package foo.bar.wiki.security;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.ProceedingJoinPoint;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.SecurityUtils;

/**
 * @author tmjee
 * @version $Date$ $Id$
 */
@Aspect
public class SecurityVerificationAspect {

    @Pointcut(
            "within(foo.bar.wiki.services.*) && " +
            "execution(* foo.bar.wiki.services.*Service.*(..)) &&" +
            "@annotation(securityVerification)"
    )
    public void allServiceMethodsAnnotatedWithSecurityVerification(
            SecurityVerification securityVerification){}


    @Around(
       "foo.bar.wiki.security.SecurityVerificationAspect.allServiceMethodsAnnotatedWithSecurityVerification(securityVerification)"
    )
    public Object performSecurityVerification(ProceedingJoinPoint pjp, SecurityVerification securityVerification) throws Throwable {
        String allPermissions = securityVerification.value();
        String[] permissions = allPermissions.split("\\|");
        if (hasAnyPermissions(permissions)) {
            return pjp.proceed();
        }
        throw new SecurityVerificationException("Lacks either of these permissions "+allPermissions);
    }

    protected boolean hasAnyPermissions(String... permissions) {
        boolean hasAnyPermission = false;
        Subject subject = SecurityUtils.getSubject();
        for (String permission : permissions) {
            permission = permission.trim();
            if ((permission.length() > 0) && (subject.isPermitted(permission))) {
                hasAnyPermission = true;
                break;
            }
        }
        return hasAnyPermission;
    }
}